// locationManager.js
import { wgs84togcj02 } from 'coordtransform';

class LocationManager {
  constructor(options = {}) {
    this.options = {
      minDistance: 10,
      minTimeInterval: 30000,
      debounceDelay: 1000,
      maxUpdateInterval: 120000,
      lowPowerThreshold: 20,
      skipInitialDebounce: true, // 新增选项
      ...options
    };

    // 状态管理
    this.lastLocation = null;
    this.lastUpdateTime = 0;
    this.isWatching = false;
    this.isBackground = false;
    this.isLowPowerMode = false;

    // 定时器引用
    this.debounceTimer = null;
    this.intervalTimer = null;

    // 回调函数
    this.locationCallback = null;
    this.errorCallback = null;

    // 事件处理器绑定
    this.locationChangeHandler = null;
    this.errorHandler = null;
    this.appShowHandler = null;
    this.appHideHandler = null;
  }


  // 公开方法
  async startWatching() {
    if (this.isWatching) return false;
     try {
       
      this._bindAppState();
  
      return new Promise((resolve, reject) => {
        uni.startLocationUpdate({
          type: 'wgs84',
          success: (res) => {
			 
            this.isWatching = true;
            this._setupListeners();
            this._startInterval();
            resolve(true);
          },
          fail: (err) => {
            this._handleError(err);
            reject(err);
          }
        });
      });
    } catch (err) {
      this._handleError(err);
      return false;
    }
  }
  stopWatching() {
    if (!this.isWatching) return;

    uni.stopLocationUpdate();
    this._cleanupListeners();
    this._clearTimers();

    this.isWatching = false;
    this.lastLocation = null;
  }

  onLocationUpdate(callback) {
    this.locationCallback = callback;
    return this;
  }

  onError(callback) {
    this.errorCallback = callback;
    return this;
  }

  // 核心逻辑

  _handleLocationUpdate(res) {
    // 首次定位且配置为跳过防抖时，立即处理
    if (!this.lastLocation && this.options.skipInitialDebounce) {
      const converted = this._convertCoordinates(res);
      const newLocation = this._createLocationObject(converted, res);
      this._updateLocationState(newLocation);
      this._notifyLocationChange(newLocation);
      return;
    }

    // 后续定位使用防抖
    if (this.debounceTimer) clearTimeout(this.debounceTimer);

    this.debounceTimer = setTimeout(() => {
      if (this._shouldIgnoreUpdate(res)) return;

      const converted = this._convertCoordinates(res);
      const newLocation = this._createLocationObject(converted, res);

      if (this._shouldTriggerUpdate(newLocation)) {
        this._updateLocationState(newLocation);
        this._notifyLocationChange(newLocation);
      }
    }, this.options.debounceDelay);
  }

  // 辅助方法
  _setupListeners() {
    this.locationChangeHandler = this._handleLocationUpdate.bind(this);
    this.errorHandler = this._handleError.bind(this);
    uni.onLocationChange(this.locationChangeHandler);
    uni.onLocationChangeError(this.errorHandler);
  }

  _cleanupListeners() {
    uni.offLocationChange(this.locationChangeHandler);
    uni.offLocationError(this.errorHandler);
    uni.offAppShow(this.appShowHandler);
    uni.offAppHide(this.appHideHandler);
  }

  _bindAppState() {
    this.appShowHandler = () => {
      this.isBackground = false;
      this._adjustLocationAccuracy('high');
    };

    this.appHideHandler = () => {
      this.isBackground = true;
      this._adjustLocationAccuracy('low');
    };

    uni.$on('app_show',this.appShowHandler);
    uni.$on('app_hide',this.appHideHandler);
  }

  _adjustLocationAccuracy(mode) {
    if (!this.isWatching) return;

    const config = {
      high: { type: 'wgs84', isHighAccuracy: true },
      low: { type: 'wgs84', isHighAccuracy: false }
    }[mode];

    uni.startLocationUpdate(config);
  }

  // 工具方法
  _convertCoordinates({ longitude, latitude }) {
   return wgs84togcj02(longitude, latitude);
	
  }

  _createLocationObject([lon, lat], original) {
    return {
      longitude: lon,
      latitude: lat,
      accuracy: original.accuracy,
      speed: original.speed,
      timestamp: Date.now()
    };
  }

  _updateLocationState(location) {
    this.lastLocation = location;
    this.lastUpdateTime = location.timestamp;
  }

  _notifyLocationChange(location) {
    this.locationCallback?.(location);
  }

  // 条件判断
  _shouldIgnoreUpdate(res) {
    return this.isBackground && 
           !this._isSignificantUpdate(res) && 
           !this._isAccuracyImproved(res);
  }

  _shouldTriggerUpdate(newLocation) {
    if (!this.lastLocation) return true;

    const distance = this._calculateDistance(
      this.lastLocation.latitude,
      this.lastLocation.longitude,
      newLocation.latitude,
      newLocation.longitude
    );

    const timeDiff = newLocation.timestamp - this.lastUpdateTime;
    const threshold = this.isLowPowerMode ? 2 : 1;

    return distance >= (this.options.minDistance * threshold) &&
           timeDiff >= (this.options.minTimeInterval * threshold);
  }

  _isSignificantUpdate(res) {
    return res.speed > 5;
  }

  _isAccuracyImproved(res) {
    return this.lastLocation && 
           res.accuracy < this.lastLocation.accuracy * 0.7;
  }

  // 数学计算
  _calculateDistance(lat1, lon1, lat2, lon2) {
    const R = 6371e3;
    const φ1 = lat1 * Math.PI/180;
    const φ2 = lat2 * Math.PI/180;
    const Δφ = (lat2 - lat1) * Math.PI/180;
    const Δλ = (lon2 - lon1) * Math.PI/180;

    const a = Math.sin(Δφ/2)**2 +
              Math.cos(φ1) * Math.cos(φ2) *
              Math.sin(Δλ/2)**2;
    return R * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
  }

_showPermissionGuide() {
  // 跨平台提示
  uni.showModal({
    title: '需要定位权限',
    content: '请在设置中允许定位权限',
    showCancel: false,
    success: () => {
      // #ifdef MP-WEIXIN
      uni.openSetting();
      // #endif

      // #ifdef H5
      alert('请通过浏览器设置启用定位权限');
      // #endif
    }
  });
}

  async _showPermissionGuide() {
    const { confirm } = await uni.showModal({
      title: '需要位置权限',
      content: '请开启位置权限以使用定位功能',
      confirmText: '去设置'
    });

    if (confirm) {
      await uni.openSetting();
      return this._checkPermissions();
    }
  }



  // 错误处理
  _handleError(error) {
    console.error('[Location Error]', error);
    this.errorCallback?.(error);
    
    if (error.errMsg.includes('auth deny')) {
      this._showPermissionGuide();
    }
  }

  // 定时任务
  _startInterval() {
    this.intervalTimer = setInterval(() => {
      uni.getLocation({
        type: 'wgs84',
        success: (res) => this._handleLocationUpdate(res),
        fail: (err) => this._handleError(err)
      });
    }, this.options.maxUpdateInterval);
  }

  _clearTimers() {
    clearTimeout(this.debounceTimer);
    clearInterval(this.intervalTimer);
  }
}

// 单例实例
export const getLocation = new LocationManager();